﻿namespace FML

#light
     

#if INTERACTIVE
#I @"C:\Program Files\Reference Assemblies\Microsoft\F#\1.0\Runtime\v2.0"
#I @"C:\Windows\Microsoft.NET\Framework\v2.0.50727"
#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"

#r "mscorlib.dll"
#r "System.dll"
#r "System.Core.dll"
#r "C:\Users\jcm\Documents\projects\Monads\libs\FsCheck.dll"
#r "C:\Users\jcm\Documents\projects\Monads\libs\NunitCore.dll"
#r "C:\Users\jcm\Documents\projects\FML\FML\obj\Debug\Monads.dll"
#endif

module WriterT =

 printf "Writer trans test\n\n"

 module Option = 

  open WriterT.Option
  open Monoid
  open WriterM

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck


  let monoid = new ListMonoid<int>() :> Monoid<int list>

  let writerOptionT = WriterOptionT(monoid);


  let (>>=) m f = writerOptionT.Bind (m, f)
  let ret = writerOptionT.Return

  let run = WriterT.Option.run
 
  quickCheck (fun  f a -> run ((ret a) >>= f)  = run (f a) )
  quickCheck (fun m -> run (m >>= ret)  = run m )
  quickCheck (fun m f g -> run ((m >>= f) >>= g)  = run (m >>= (fun x -> f x >>= g)) )

 module List = 

  open WriterT.List
  open Monoid
  open WriterM

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck


  let monoid = new ListMonoid<int>() :> Monoid<int list>

  let writerListT = WriterListT(monoid);


  let (>>=) m f = writerListT.Bind (m, f)
  let ret = writerListT.Return

  let run = WriterT.List.run
 
  quickCheck (fun  f a -> run ((ret a) >>= f)  = run (f a) )
  quickCheck (fun m -> run (m >>= ret)  = run m )
  quickCheck (fun m f g -> run ((m >>= f) >>= g)  = run (m >>= (fun x -> f x >>= g)) )


 module Error = 

  open WriterT.Error
  open Monoid
  open WriterM

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck


  let monoid = new ListMonoid<int>() :> Monoid<int list>

  let writerErrorT = WriterErrorT(monoid);


  let (>>=) m f = writerErrorT.Bind (m, f)
  let ret = writerErrorT.Return

  let run = WriterT.Error.run
 
  quickCheck (fun  f a -> run ((ret a) >>= f)  = run (f a) )
  quickCheck (fun m -> run (m >>= ret)  = run m )
  quickCheck (fun m f g -> run ((m >>= f) >>= g)  = run (m >>= (fun x -> f x >>= g)) )


 module Reader = 

  open WriterT.Reader
  open Monoid
  open WriterM

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck


  let monoid = new ListMonoid<int>() :> Monoid<int list>

  let writerReaderT = WriterReaderT(monoid);


  let (>>=) m f = writerReaderT.Bind (m, f)
  let ret = writerReaderT.Return

  let runW = WriterT.Reader.run
  let runR = ReaderM.run
 
  quickCheck (fun  f a env -> runR (runW ((ret a) >>= f)) env  = runR (runW (f a) ) env)
  quickCheck (fun m env -> runR (runW (m >>= ret)) env  = runR (runW m) env )
  quickCheck (fun m f g env -> runR (runW ((m >>= f) >>= g)) env  = runR (runW (m >>= (fun x -> f x >>= g))) env )
